package com.arvin.faceDetect.ui

import android.Manifest
import android.content.pm.PackageManager
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Toast
import androidx.activity.result.contract.ActivityResultContracts
import androidx.camera.core.Camera
import androidx.camera.core.CameraSelector
import androidx.camera.core.ImageAnalysis
import androidx.camera.core.ImageProxy
import androidx.camera.core.Preview
import androidx.camera.lifecycle.ProcessCameraProvider
import androidx.core.content.ContextCompat
import androidx.fragment.app.Fragment
import androidx.lifecycle.lifecycleScope
import com.arvin.faceDetect.databinding.FragmentAddFaceBinding
import com.arvin.faceDetect.db.FaceDatabase
import com.arvin.faceDetect.db.FaceEntity
import com.arvin.faceDetect.ml.FaceFeatureExtractor
import com.arvin.faceDetect.model.CameraSettings
import com.arvin.faceDetect.utils.Settings
import com.arvin.faceDetect.utils.toBitmap
import com.google.mlkit.vision.common.InputImage
import com.google.mlkit.vision.face.FaceDetection
import com.google.mlkit.vision.face.FaceDetectorOptions
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import java.util.UUID
import java.util.concurrent.ExecutorService
import java.util.concurrent.Executors

class AddFaceFragment : Fragment() {
    private var _binding: FragmentAddFaceBinding? = null
    private val binding get() = _binding!!

    private var cameraExecutor: ExecutorService? = null
    private var camera: Camera? = null
    private var imageAnalyzer: ImageAnalysis? = null
    private lateinit var faceFeatureExtractor: FaceFeatureExtractor
    private var latestFace: com.google.mlkit.vision.face.Face? = null
    private var latestBitmap: android.graphics.Bitmap? = null
    private var isProcessingFrame = false

    private val requestPermissionLauncher = registerForActivityResult(
        ActivityResultContracts.RequestPermission()
    ) { isGranted ->
        if (isGranted) {
            startCamera()
        } else {
            Toast.makeText(context, "需要相机权限才能添加人脸", Toast.LENGTH_SHORT).show()
        }
    }

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View {
        _binding = FragmentAddFaceBinding.inflate(inflater, container, false)
        return binding.root
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        
        faceFeatureExtractor = FaceFeatureExtractor(requireContext())
        cameraExecutor = Executors.newSingleThreadExecutor()

        setupCapture()

        if (allPermissionsGranted()) {
            startCamera()
        } else {
            requestPermissionLauncher.launch(Manifest.permission.CAMERA)
        }
    }

    private fun setupCapture() {
        binding.btnCapture.setOnClickListener {
            val name = binding.etName.text.toString()
            if (name.isBlank()) {
                Toast.makeText(context, "请输入姓名", Toast.LENGTH_SHORT).show()
                return@setOnClickListener
            }

            val face = latestFace
            val bitmap = latestBitmap
            if (face == null || bitmap == null) {
                Toast.makeText(context, "未检测到人脸", Toast.LENGTH_SHORT).show()
                return@setOnClickListener
            }

            viewLifecycleOwner.lifecycleScope.launch {
                saveFace(name, face, bitmap)
            }
        }
    }

    private suspend fun saveFace(name: String, face: com.google.mlkit.vision.face.Face, bitmap: android.graphics.Bitmap) {
        withContext(Dispatchers.IO) {
            try {
                val faceBitmap = faceFeatureExtractor.cropFace(bitmap, face.boundingBox)
                val features = faceFeatureExtractor.extractFeatures(faceBitmap)
                
                val faceEntity = FaceEntity(
                    id = UUID.randomUUID().toString(),
                    name = name,
                    faceImage = faceBitmap,
                    faceFeatures = features,
                    createTime = System.currentTimeMillis()
                )
                
                FaceDatabase.getDatabase(requireContext()).faceDao().insertFace(faceEntity)
                
                withContext(Dispatchers.Main) {
                    Toast.makeText(context, "人脸添加成功", Toast.LENGTH_SHORT).show()
                    parentFragmentManager.popBackStack()
                }
            } catch (e: Exception) {
                withContext(Dispatchers.Main) {
                    Toast.makeText(context, "人脸添加失败: ${e.message}", Toast.LENGTH_SHORT).show()
                }
            }
        }
    }

    private fun startCamera() {
        val cameraProviderFuture = ProcessCameraProvider.getInstance(requireContext())

        cameraProviderFuture.addListener({
            val cameraProvider = cameraProviderFuture.get()

            val preview = Preview.Builder()
                .build()
                .also {
                    it.setSurfaceProvider(binding.viewFinder.surfaceProvider)
                }

            imageAnalyzer = ImageAnalysis.Builder()
                .setBackpressureStrategy(ImageAnalysis.STRATEGY_KEEP_ONLY_LATEST)
                .build()
                .also {
                    it.setAnalyzer(cameraExecutor ?: return@also, FaceAnalyzer { faces, bitmap, rotation ->
                        _binding?.let { binding ->
                            if (!isProcessingFrame) {
                                isProcessingFrame = true
                                val cameraFacing = Settings.getCameraFacing(requireContext())
                                binding.faceOverlayView.updateFaces(
                                    faces,
                                    Settings.isShowFaceRect(requireContext()),
                                    bitmap.width,
                                    bitmap.height,
                                    rotation,
                                    cameraFacing == CameraSettings.CAMERA_FACING_FRONT
                                )
                                if (faces.isNotEmpty()) {
                                    latestFace = faces[0]
                                    latestBitmap = bitmap
                                }
                                isProcessingFrame = false
                            }
                        }
                    })
                }

            try {
                cameraProvider.unbindAll()
                val cameraFacing = Settings.getCameraFacing(requireContext())
                val cameraSelector = when (cameraFacing) {
                    CameraSettings.CAMERA_FACING_FRONT -> CameraSelector.DEFAULT_FRONT_CAMERA
                    CameraSettings.CAMERA_FACING_BACK -> CameraSelector.DEFAULT_BACK_CAMERA
                    else -> CameraSelector.DEFAULT_FRONT_CAMERA
                }
                camera = cameraProvider.bindToLifecycle(
                    viewLifecycleOwner,
                    cameraSelector,
                    preview,
                    imageAnalyzer
                )

                // 设置预览尺寸
                binding.viewFinder.post {
                    binding.faceOverlayView.setPreviewSize(
                        binding.viewFinder.width,
                        binding.viewFinder.height
                    )
                    // 从设置中读取显示开关状态
                    binding.faceOverlayView.setShowFaceRect(Settings.isShowFaceRect(requireContext()))
                    binding.faceOverlayView.setShowEyeRect(Settings.isShowEyeRect(requireContext()))
                }
            } catch (e: Exception) {
                e.printStackTrace()
            }
        }, ContextCompat.getMainExecutor(requireContext()))
    }

    private fun allPermissionsGranted() = ContextCompat.checkSelfPermission(
        requireContext(), Manifest.permission.CAMERA
    ) == PackageManager.PERMISSION_GRANTED

    override fun onDestroyView() {
        super.onDestroyView()
        imageAnalyzer = null
        camera = null
        cameraExecutor?.shutdown()
        cameraExecutor = null
        _binding = null
    }

    private class FaceAnalyzer(
        private val listener: (faces: List<com.google.mlkit.vision.face.Face>, bitmap: android.graphics.Bitmap, rotation: Int) -> Unit
    ) : ImageAnalysis.Analyzer {
        private val detector = FaceDetection.getClient(
            FaceDetectorOptions.Builder()
                .setPerformanceMode(FaceDetectorOptions.PERFORMANCE_MODE_FAST)
                .setLandmarkMode(FaceDetectorOptions.LANDMARK_MODE_ALL)
                .setClassificationMode(FaceDetectorOptions.CLASSIFICATION_MODE_ALL)
                .build()
        )

        @androidx.camera.core.ExperimentalGetImage
        override fun analyze(imageProxy: ImageProxy) {
            val mediaImage = imageProxy.image
            if (mediaImage != null) {
                val rotation = imageProxy.imageInfo.rotationDegrees
                val image = InputImage.fromMediaImage(
                    mediaImage,
                    rotation
                )

                detector.process(image)
                    .addOnSuccessListener { faces ->
                        val bitmap = imageProxy.toBitmap()
                        listener(faces, bitmap, rotation)
                    }
                    .addOnFailureListener {
                        it.printStackTrace()
                    }
                    .addOnCompleteListener {
                        imageProxy.close()
                    }
            } else {
                imageProxy.close()
            }
        }
    }
} 